package com.ks.user.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.ks.core.base.OperationContext;
import com.ks.core.constant.Const;
import com.ks.core.dto.SearchCriteriaBase;
import com.ks.core.exception.BizException;
import com.ks.core.exception.BizExceptionEnum;
import com.ks.core.exception.GunsException;
import com.ks.core.exception.GunsExceptionEnum;
import com.ks.core.util.*;
import com.ks.user.controller.response.UserBaseDto;
import com.ks.user.dao.RedisDao;
import com.ks.user.entity.OrgBase;
import com.ks.user.entity.OrgEmployee;
import com.ks.user.entity.UserBase;
import com.ks.user.dao.UserBaseMapper;
import com.ks.user.service.*;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author kingdee123
 * @since 2020-11-18
 */
@Service
public class UserBaseServiceImpl extends _ServiceBase<UserBaseMapper, UserBase> implements IUserBaseService {
    @Resource
    private RedisDao redis;

    @Resource
    private UserBaseMapper userBaseMapper;

    @Resource
    private IOrgTenantService orgTenantService;

    @Resource
    private IOrgEmployeeService orgEmployeeService;

    @Resource
    private IOrgBaseService orgBaseService;


    @Override
    public String TokenStorage(String userId) {
        //生成token
        String token = UUID.randomUUID().toString().replaceAll("-", "");
        //存储redis里
        redis.setKey(userId + "_" + "key", token, 70000);
        redis.setKey(token, userId, 70000);
        return token;
    }

    @Override
    public Map<String, Object> login(String mobile, String password, String code, String username,Integer tenantId) {
        Map<String, Object> map = new HashMap<>();
        UserBaseDto userBaseDto = new UserBaseDto();
        String authToken = "";
        UserBase userBase = new UserBase();
        //手机号 +验证码登录 优先级最高
        if (ToolUtil.isNotEmpty(mobile) && ToolUtil.isNotEmpty(code)) {
            checkCode(mobile, "type", code);
            userBase = selectMobile(mobile,tenantId);
            if (ToolUtil.isNotEmpty(userBase)) {
                if (!userBase.getTenantID().equals(tenantId)){
                        throw new GunsException(BizExceptionEnum.TENANT_IS_NULL);
                }
                if (userBase.getCUserType().equals("T")) {
                    authToken = getAuthToken(userBase);
                    userBase.setAuthToken(authToken);
                    userBaseDto = getUserBase(userBase);
                } else {
                    throw new GunsException(BizExceptionEnum.USER_IS_NULL);
                }
            }else {
                throw new GunsException(BizExceptionEnum.USER_IS_NULL);
            }
        } else if (ToolUtil.isNotEmpty(password)) {
            //用户名密码登录
            userBase = selectUserName(username);
            if (ToolUtil.isNotEmpty(userBase)) {
                if (!userBase.getTenantID().equals(tenantId)){
                    throw new GunsException(BizExceptionEnum.TENANT_IS_NULL);
                }
                if (userBase.getCUserType().equals("T")) {
                    boolean equals = userBase.getIPassWord().equals(password);
                    if (equals) {
                        authToken = getAuthToken(userBase);
                        userBase.setAuthToken(authToken);
                        userBaseDto = getUserBase(userBase);
                    } else {
                        throw new GunsException(BizExceptionEnum.ACCOUNT_PASSWORD_ERROR);
                    }
                } else {
                    throw new GunsException(BizExceptionEnum.USER_IS_NULL);
                }
            } else {
                throw new GunsException(BizExceptionEnum.ACCOUNT_PASSWORD_ERROR);
            }
        }
        map.put("userBaseDto", userBaseDto);
        redis.setKey(userBaseDto.getUserId().toString(), JsonUtil.objectToJsonStr(userBase));
        return map;
    }

    @Override
    public int setTenantAdmin(OperationContext operationContext, String mobile, String name, int tenantId, int orgId) {
        UserBase userBase1 = selectMobile(mobile,tenantId);
        if (ToolUtil.isNotEmpty(userBase1)) {
            throw new GunsException("该手机号已经设置成为管理员用户了");
        }

        String Salt = StringUtil.getStringRandom(8);
        UserBase userBase = new UserBase();
        userBase.setITel(mobile);
        userBase.setIAdmin(Const.SysUser.YES);
        userBase.setIUserName(name);
        userBase.setIRealName(name);
        userBase.setIPassWord(MD5Util.getMD5(MD5Util.getMD5("123456") + Salt));
        userBase.setCSalt(Salt);
        userBase.setINickName(name);
        userBase.setCUserType(Const.SysUser.UserBaseType);
        userBase.setCreateUserID(operationContext.getUserId().intValue());
        userBase.setTenantID(tenantId);
        Integer insert = userBaseMapper.insert(userBase);
        return insert;
    }

    @Override
    public Map<String, Object> getUserInfo(int userId) {
        Map<String, Object> map = new HashMap<>();
        UserBase userBase = queryUserIdInfo(userId);
        if (ToolUtil.isNotEmpty(userBase)) {
            map.put("userBase", userBase);
            return map;
        } else {
            throw new GunsException(BizExceptionEnum.USER_IS_NULL);
        }
    }

    @Override
    public int ResetPassword(int userId, String mobile, String code) {
        checkCode(mobile, "type", code);
        UserBase userBase = userBaseMapper.selectById(userId);
        String Salt = StringUtil.getStringRandom(8);
        if (ToolUtil.isNotEmpty(userBase)) {
            userBase.setIPassWord(MD5Util.getMD5(MD5Util.getMD5("123456") + Salt));
            userBase.setCSalt(Salt);
        } else {
            throw new GunsException(BizExceptionEnum.USER_IS_NULL);
        }
        Integer integer = userBaseMapper.updateById(userBase);
        return integer;
    }

    @Override
    public int SignOut(OperationContext operationContext) {
        redis.delKey(operationContext.getUserId().toString());
        String value = redis.getValue(operationContext.getUserId().toString());
        if (ToolUtil.isNotEmpty(value)) {
            return 0;
        }
        return 1;
    }

    public UserBase queryUserIdInfo(int userId) {
        UserBase userBase = new UserBase();
        userBase.setId(userId);
        userBase.setCLock(Const.DEL_FLAG_NORMAL);
        UserBase base = userBaseMapper.selectOne(userBase);
        return base;
    }


    public UserBaseDto getUserBase(UserBase userBase) {
        UserBaseDto userBaseDto = new UserBaseDto();
        userBaseDto.setAuthToken(userBase.getAuthToken());
        userBaseDto.setUserId(userBase.getId());
        userBaseDto.setAvatar(userBase.getIfavatar());
        userBaseDto.setLoginTime(new Date());
        userBaseDto.setNickName(userBase.getINickName());
        userBaseDto.setOrgID(userBase.getOrgID());
        userBaseDto.setRealName(userBase.getIRealName());
        userBaseDto.setUserType(userBase.getCUserType());
        userBaseDto.setTenantID(userBase.getTenantID());
        userBaseDto.setUserName(userBase.getIUserName());
        userBaseDto.setSign(userBase.getISign());
        return userBaseDto;
    }

    /**
     * 生成token
     *
     * @param userBase
     * @return
     */
    @Override
    public String getAuthToken(UserBase userBase) {
        String auth = userBase.getTenantID() + ":" + userBase.getOrgID() + ":" + userBase.getOrgSubID() + ":" + userBase.getId() + ":" + new Date().getTime();
        String md5 = MD5Util.getMD5(auth + ":" + userBase.getCSalt());
        String token = auth + ":" + md5;
        return token;
    }

    /*@Override
    public Map<String, Object> log(String mobile, String password) {
        Map<String, Object> map = new HashMap<>();
        UserBase userBase = selectMobile(mobile);
        if (ToolUtil.isNotEmpty(userBase)) {
            boolean equals = userBase.getIPassWord().equals(password);
            if (!equals) {
                throw new GunsException(BizExceptionEnum.ACCOUNT_PASSWORD_ERROR);
            }
            map.put("userBase", userBase);
        }
        if (ToolUtil.isNotEmpty(userBase.getId()) && userBase.getId() > 0) {
            String token = TokenStorage(String.valueOf(userBase.getId()));
            map.put("token", "Bearer " + token);
        }
        return map;
    }*/

    @Override
    public void checkCode(String mobile, String type, String code) {
        if ("521314".equals(code)) {
            return;
        }
        String key = mobile + "_" + type;
        String redisCode = redis.getValue(key);
        if (ToolUtil.isEmpty(redisCode) || !code.equals(redisCode)) {
            throw new GunsException(BizExceptionEnum.CODE_NOT_VALIDY);
        }
        return;
    }

    @Override
    public UserBase selectMobile(String mobile,int tenantId) {
        UserBase userBase = new UserBase();
        userBase.setITel(mobile);
        userBase.setCLock(Const.DEL_FLAG_NORMAL);
        userBase.setTenantID(tenantId);
        UserBase user = userBaseMapper.selectOne(userBase);
        return user;
    }

    @Override
    public UserBase selectUserName(String username) {
        UserBase userBase = new UserBase();
        userBase.setIUserName(username);
        userBase.setCLock(Const.DEL_FLAG_NORMAL);
        UserBase user = userBaseMapper.selectOne(userBase);
        return user;
    }

    @Override
    public UserBase getQueryTenant(OperationContext operationContext, int userId) {
        String id = operationContext.getUserId().toString();
        if (id.equals(String.valueOf(userId))) {
            UserBase userBase = userBaseMapper.selectById(userId);
            if (ToolUtil.isNotEmpty(userBase)) {
                return userBase;
            }
        } else {
            UserBase userBase = userBaseMapper.selectById(Integer.valueOf(id));
            UserBase base = userBaseMapper.selectById(userId);
            if (ToolUtil.isNotEmpty(userBase) && ToolUtil.isNotEmpty(base)) {
                if (userBase.getTenantID().equals(base.getTenantID())) {
                    return base;
                }

            }
        }
        return null;
    }

    @Override
    public int updateTenantUser(OperationContext operationContext, UserBase userBase) {
        String userId = operationContext.getUserId().toString();
        if (userId.equals(userBase.getId())) {
            Integer integer = userBaseMapper.updateById(userBase);
            return integer;
        } else {
            UserBase base = userBaseMapper.selectById(Integer.valueOf(userId));
            if (ToolUtil.isNotEmpty(base)) {
                if (base.getTenantID().equals(userBase.getTenantID())) {
                    Integer integer = userBaseMapper.updateById(userBase);
                    return integer;
                }
            }
        }
        return 0;
    }

    @Override
    public int changeTenantPassword(OperationContext operationContext, String mobile, String code, String password, String newPassword) {
        String userId = operationContext.getUserId().toString();
        UserBase userBase = userBaseMapper.selectById(userId);
        if (ToolUtil.isNotEmpty(mobile) && ToolUtil.isNotEmpty(code)) {
            checkCode(mobile, "type", code);
            if (ToolUtil.isNotEmpty(userBase)) {
                userBase.setIPassWord(MD5Util.getMD5(newPassword + userBase.getCSalt()));
                Integer integer = userBaseMapper.updateById(userBase);
                return integer;
            }
        } else {
            //说明用户使用旧密码来修改
            if (MD5Util.getMD5(password + userBase.getCSalt()).equals(userBase.getIPassWord())) {
                userBase.setIPassWord(MD5Util.getMD5(newPassword + userBase.getCSalt()));
                Integer integer = userBaseMapper.updateById(userBase);
                return integer;
            } else {
                throw new GunsException(BizExceptionEnum.ACCOUNT_PASSWORD_ERROR);
            }
        }
        return 0;
    }

    @Override
    public Map<String, Object> getUserList(OperationContext operationContext, SearchCriteriaBase searchCriteriaBase) {
        Map<String, Object> map = new HashMap<>();
        ArrayList<SearchCriteriaBase.matchField> fields = searchCriteriaBase.getFields();
        for (SearchCriteriaBase.matchField field : fields) {
            if ("orgId".equals(field.getName())) {
                OrgBase orgBase = orgBaseService.selectById(Integer.getInteger(field.getValue()));
                if (ToolUtil.isNotEmpty(orgBase)) {
                    List<UserBase> userList = userBaseMapper.getUserList(orgBase.getIMechanismCode(), searchCriteriaBase.getPageIndex(), searchCriteriaBase.getLimit());
                    int userListCount = userBaseMapper.getUserListCount(orgBase.getIMechanismCode());
                    map.put("userList", userList);
                    map.put("count", userListCount);
                }
            }
        }
        return map;
    }


    @Override
    public int ResetEmployeeUserPwd(OperationContext operationContext, String type, int employeeId) {
        if (type.equals("CJ")) {
            int i = orgBaseService.addUserBase(operationContext, employeeId);
            return i;
        } else if (type.equals("SZ")) {
            OrgEmployee orgEmployee = orgEmployeeService.getOrgEmployee(employeeId);
            if (ToolUtil.isNotEmpty(orgEmployee) && orgEmployee.getIUserID() > 0) {
                OrgBase orgBase = orgBaseService.selectById(orgEmployee.getCOrgNodeID());
                if (ToolUtil.isNotEmpty(orgBase) && orgBase.getIMechanismType() < 3) {
                    UserBase base = userBaseMapper.selectById(orgEmployee.getIUserID());
                    base.setIAdmin(Const.SysUser.YES);
                    Integer integer = userBaseMapper.updateById(base);
                    return integer;
                } else {
                    throw new GunsException("该员工的节点不是在组织或机构下。");
                }
            } else {
                throw new GunsException(BizExceptionEnum.USER_IS_NULL);
            }
        } else if (type.equals("CZ")) {
            OrgEmployee orgEmployee = orgEmployeeService.getOrgEmployee(employeeId);
            if (ToolUtil.isNotEmpty(orgEmployee) && orgEmployee.getIUserID() > 0) {
                UserBase employeeUser = userBaseMapper.selectById(orgEmployee.getIUserID());
                employeeUser.setIPassWord(MD5Util.getMD5(MD5Util.getMD5("66666") + employeeUser.getCSalt()));
                Integer integer = userBaseMapper.updateById(employeeUser);
                return integer;
            }
        } else if (type.equals("QX")){
            OrgEmployee orgEmployee = orgEmployeeService.getOrgEmployee(employeeId);
            if (ToolUtil.isNotEmpty(orgEmployee) && orgEmployee.getIUserID() > 0) {
                OrgBase orgBase = orgBaseService.selectById(orgEmployee.getCOrgNodeID());
                if (ToolUtil.isNotEmpty(orgBase) && orgBase.getIMechanismType() < 3) {
                    UserBase base = userBaseMapper.selectById(orgEmployee.getIUserID());
                    base.setIAdmin(Const.SysUser.NO);
                    Integer integer = userBaseMapper.updateById(base);
                    return integer;
                } else {
                    throw new GunsException("该员工的节点不是在组织或机构下。");
                }
            } else {
                throw new GunsException(BizExceptionEnum.USER_IS_NULL);
            }
        }else {
            throw new GunsException("参数类型错误。。。");
        }
        return 0;
    }


    @Override
    public int setUserLock(int userId, int lock) {
        UserBase userBase = userBaseMapper.selectById(userId);
        if (ToolUtil.isNotEmpty(userBase)) {
            userBase.setCLock(lock);
            Integer integer = userBaseMapper.updateById(userBase);
            return integer;
        }
        return 0;
    }

    @Override
    public UserBase getUserBaseInfo(OperationContext operationContext) {
        UserBase userBase = userBaseMapper.selectById(operationContext.getUserId());
        if (ToolUtil.isNotEmpty(userBase)) {
            OrgEmployee employeeInfo = orgEmployeeService.getEmployeeInfo(operationContext.getUserId().intValue());
            if (ToolUtil.isNotEmpty(employeeInfo)) {
                userBase.setIPost(employeeInfo.getIPost());
            }
            return userBase;
        }
        return null;
    }

    @Override
    public int updateMobile(OperationContext operationContext, String mobile, String code, String password) {
        checkCode(mobile, "type", code);
        UserBase userBase = userBaseMapper.selectById(operationContext.getUserId().intValue());
        if (ToolUtil.isNotEmpty(userBase)) {
            if (userBase.getIPassWord().equals(MD5Util.getMD5(password + userBase.getCSalt()))) {
                UserBase base = getUserBase(operationContext, mobile);
                if (ToolUtil.isNotEmpty(base)) {
                    throw new GunsException(BizExceptionEnum.MOBILE_REPEAT);
                } else {
                    userBase.setITel(mobile);
                    Integer integer = userBaseMapper.updateById(userBase);
                    return integer;
                }
            }
        }
        return 0;
    }


    public UserBase getUserBase(OperationContext operationContext, String mobile) {
        UserBase userBase = new UserBase();
        userBase.setDelMark(Const.DEL_FLAG_NORMAL);
        userBase.setITel(mobile);
        userBase.setTenantID(operationContext.getTenantId().intValue());
        UserBase base = userBaseMapper.selectOne(userBase);
        return base;
    }

}
